Skip to main content

Chroot FTP User

Why it matters​

An FTP account with broad filesystem access creates avoidable risk. Chroot confinement limits the account to a controlled directory, reducing impact from mistakes or stolen credentials.

Why this approach​

Combining FTP confinement (chroot) with shell restriction (/usr/sbin/nologin) gives collaborators file access without interactive server access.

When to use it​

Use this for designers, content editors, or contractors who need limited file transfer access but should not receive SSH access.

Concept Overview​

GoalDescription
Chroot isolationUser is jailed to a specific root path
FTP-only accessLogin allowed through FTP service, not shell
Scoped editingRestrict writes to approved WordPress directories
Security boundaryMinimize host exposure for third-party users

Environment Preparation​

Example site root:

/home/wpstrategist/public_html/

Example target scope for editor access:

/home/wpstrategist/public_html/wp-content/themes/

Install and Enable FTP Service​

sudo apt update
sudo apt install vsftpd -y
sudo systemctl enable --now vsftpd

Configure vsftpd​

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backup
sudo nano /etc/vsftpd.conf

Recommended baseline:

listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
allow_writeable_chroot=YES
user_sub_token=$USER
local_root=/home/$USER/public_html
pam_service_name=vsftpd
xferlog_enable=YES
xferlog_std_format=YES

Restart service:

sudo systemctl restart vsftpd

Create FTP-Only User​

sudo adduser designer --home /home/designer --shell /usr/sbin/nologin

Verify shell policy:

grep designer /etc/passwd

Expected shell value should end with:

/usr/sbin/nologin

Prepare Directory and Ownership​

sudo mkdir -p /home/designer/public_html/wp-content/themes
sudo chown -R designer:designer /home/designer
sudo chmod -R 755 /home/designer

Optional symlink to shared theme path:

sudo ln -s /home/wpstrategist/public_html/wp-content/themes /home/designer/public_html/wp-content/themes

Optional Selective Chroot List​

Use this when only specific users should be jailed:

chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list

Add user to list:

echo "designer" | sudo tee -a /etc/vsftpd.chroot_list
sudo systemctl restart vsftpd

Verification Checklist​

CheckCommandExpected Result
Shell disabledgrep designer /etc/passwd/usr/sbin/nologin
FTP loginFTP client loginSuccess
SSH blockedssh designer@serverLogin denied
Path confinementNavigate above user root in FTP clientAccess denied
File uploadUpload test file in allowed pathSuccess

Troubleshooting​

ErrorLikely CauseFix
500 OOPS ... writable root inside chroot()Chroot writable root restrictionSet allow_writeable_chroot=YES
530 Login incorrectCredential or shell mismatchVerify password and account shell
Empty FTP directoryWrong local_root pathCorrect local_root in config
User still can SSHShell is not nologinUpdate user shell and retry

Summary​

Chrooted FTP users are a practical least-privilege pattern for controlled collaboration. This setup keeps access narrow, auditable, and safer than giving full shell accounts.